<?php

namespace App\Models;

use Database\Factories\UserFactory;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Eloquent;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Notifications\DatabaseNotificationCollection;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Carbon;
use Laravel\Sanctum\HasApiTokens;
use Laravel\Sanctum\PersonalAccessToken;

/**
 * App\Models\User
 *
 * @property int $id
 * @property string $name
 * @property string $email
 * @property string|null $email_verified_at
 * @property string $password
 * @property string|null $remember_token
 * @property Carbon|null $created_at
 * @property Carbon|null $updated_at
 * @property-read Collection|BankCard[] $bankCard
 * @property-read int|null $bank_card_count
 * @property-read Order|null $largestOrder
 * @property-read Order|null $latestOrder
 * @property-read DatabaseNotificationCollection|DatabaseNotification[] $notifications
 * @property-read int|null $notifications_count
 * @property-read Order|null $oldestOrder
 * @property-read Phone|null $phone
 * @property-read Collection|role[] $roles
 * @property-read int|null $roles_count
 * @property-read Collection|PersonalAccessToken[] $tokens
 * @property-read int|null $tokens_count
 * @method static UserFactory factory(...$parameters)
 * @method static Builder|User newModelQuery()
 * @method static Builder|User newQuery()
 * @method static Builder|User query()
 * @method static Builder|User whereCreatedAt($value)
 * @method static Builder|User whereEmail($value)
 * @method static Builder|User whereEmailVerifiedAt($value)
 * @method static Builder|User whereId($value)
 * @method static Builder|User whereName($value)
 * @method static Builder|User wherePassword($value)
 * @method static Builder|User whereRememberToken($value)
 * @method static Builder|User whereUpdatedAt($value)
 * @mixin Eloquent
 */
class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable, HasDateTimeFormatter;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     *  获取与用户对应的电话记录
     */
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }

    /**
     *  获取银行卡信息
     */
    public function bankCard()
    {
        return $this->hasMany(BankCard::class);
    }

    /** 一对多检索  **/
    /**
     *  检索用户最新的订单 （默认根据表单主键检索最新订单，主键必须可以排序）
     */
    public function latestOrder()
    {
        return $this->hasOne(Order::class)->latestOfMany();
    }

    /**
     *  检索用户最早的订单 （默认根据表单主键检索最早订单，主键必须可以排序）
     */
    public function oldestOrder()
    {
        return $this->hasOne(Order::class)->oldestOfMany();
    }

    // 使用不同的排序条件
    /**
     * 检索用户最贵的订单 （ofMany 方法可以接收两个参数，第一个是：可排序的列、第二个是：聚合函数名 min|max ）
     */
    public function largestOrder()
    {
        return $this->hasOne(Order::class)->ofMany('amount', 'max');
    }

    /**
     *  用户所拥有的角色
     */
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}
